package util

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
)

// CBC模式+PKCS7 填充

// AesCBCEncrypt encrypts data with key and iv using AES algorithm.
// You must make sure the length of key and iv is 16 bytes. This function does not perform any padding for key or iv.
func AesCBCEncrypt(data, key, iv string, paddingMode PaddingMode) string {
	block, err := aes.NewCipher([]byte(key))
	if err != nil {
		return ""
	}

	src := Padding(paddingMode, []byte(data), block.BlockSize())
	encryptData := make([]byte, len(src))
	mode := cipher.NewCBCEncrypter(block, []byte(iv))
	mode.CryptBlocks(encryptData, src)
	return base64.StdEncoding.EncodeToString(encryptData)
}

// CBCDecrypt decrypts data with key and iv using AES algorithm.
// paddingMode 只会影响最后生成 []byte 的大小，不会影响解密的过程
func CBCDecrypt(data, key, iv []byte, paddingMode PaddingMode) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	decryptData := make([]byte, len(data))

	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(decryptData, data)

	original, _ := UnPadding(paddingMode, decryptData)
	return original, nil
}
